package com.tql.mall.cart.service.impl;

import com.tql.mall.cart.service.CartService;
import com.tql.mall.common.constant.RedisConstant;
import com.tql.mall.model.cart.CartInfo;
import com.tql.mall.model.product.SkuInfo;
import com.tql.mall.product.client.ProductFeignClient;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: tyk
 * @Date: 2023/5/25 19:48
 * @Description:
 */
@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private ProductFeignClient productFeignClient;

    @Override
    public void addToCart(Long skuId, Integer skuNum, String userId) {

        // 购物车的key
        String key = getKey(userId);

        // 获取购物车
        BoundHashOperations<String, String, CartInfo> bound = redisTemplate.boundHashOps(key);

        // 判断购物车是否已经含有该商品，若有则更新数量
        CartInfo cart = bound.get(skuId.toString());
        if (cart != null) {
            cart.setSkuNum(cart.getSkuNum() + skuNum);
            cart.setUpdateTime(new Date());
            cart.setSkuPrice(productFeignClient.getSkuPrice(skuId));
        } else {
            SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);
            cart = new CartInfo(
                    userId, skuId, skuInfo.getShopId(), skuInfo.getPrice(), skuInfo.getPrice(),
                    skuNum, skuInfo.getSkuName(), skuInfo.getSkuDefaultImg(),
                    new Date(), new Date()
            );
        }
        bound.put(skuId.toString(), cart);
    }

@Override
public List<CartInfo> cartList(String userId, String userTempId) {

    List<CartInfo> cartInfoList = null;

    // 临时用户ID：获取未登录的购物车数据
    if (!StringUtils.isEmpty(userTempId)) {
        // 购物车的key
        String key = getKey(userTempId);
        // 购物车
        cartInfoList = redisTemplate.boundHashOps(key).values();
    }

    // 用户ID：获取登录的购物车数据
    if (!StringUtils.isEmpty(userId)) {
        // 购物车的key
        String key = getKey(userId);
        // 合并购车
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            // 合并购物车
            BoundHashOperations<String, String, CartInfo> bound = redisTemplate.boundHashOps(key);
            cartInfoList.forEach(
                    e -> {
                        // 判断登录后的购物车是否包含当前商品
                        if (bound.hasKey(e.getSkuId().toString())) {
                            // 更新登录后的购物车中该商品的信息
                            CartInfo cart = bound.get(e.getSkuId().toString());
                            if (cart != null) {
                                cart.setSkuNum(cart.getSkuNum() + e.getSkuNum());   // 商品数量
                                cart.setUpdateTime(new Date());                     // 修改更新时间
                                if (e.getIsChecked() == 1) cart.setIsChecked(1);    // 选中状态
                                bound.put(cart.getSkuId().toString(), cart);
                            }
                        } else {
                            // 添加到登录后的购物车
                            e.setUserId(userId);            // 替换掉临时用户ID
                            e.setUpdateTime(new Date());    // 修改更新时间
                            bound.put(e.getSkuId().toString(), e);
                        }
                    }
            );
        }
        // 已登录则清除未登录的购物车信息
        if (!StringUtils.isEmpty(userTempId)) redisTemplate.delete(getKey(userTempId));
        // 获取合并后的数据
        cartInfoList = redisTemplate.boundHashOps(key).values();
    }

    // 按更新时间降序
    if (!CollectionUtils.isEmpty(cartInfoList)) {
        cartInfoList.sort((e1, e2) -> DateUtils.truncatedCompareTo(
                e2.getUpdateTime(), e1.getUpdateTime(), Calendar.SECOND
        ));
        return cartInfoList;
    }

    return new ArrayList<>();
}

    @Override
    public void checkCart(String userId, Long skuId, Integer isChecked) {
        // 获取数据列表
        BoundHashOperations<String, String, CartInfo> bound = redisTemplate.boundHashOps(getKey(userId));
        // 判断skuID是否存在
        String skuIdStr = skuId.toString();
        if (bound.hasKey(skuIdStr)) {
            CartInfo cartInfo = bound.get(skuIdStr);
            cartInfo.setIsChecked(isChecked);   // 修改选中状态
            bound.put(skuIdStr, cartInfo);
        }
    }

    @Override
    public void deleteCart(String userId, Long skuId) {
        // 删除购物车
        redisTemplate.boundHashOps(getKey(userId)).delete(skuId.toString());
    }

    @Override
    public void deleteChecked(String userId) {
        // 获取数据列表
        BoundHashOperations<String, String, CartInfo> bound = redisTemplate.boundHashOps(getKey(userId));
        // 删除已选中的商品
        List<CartInfo> list = bound.values();
        if (!CollectionUtils.isEmpty(list)) {
            for (CartInfo e : list) {
                if (e.getIsChecked() == 1) bound.delete(e.getSkuId().toString());
            }
        }
    }

    @Override
    public List<CartInfo> getCartCheckedList(String userId) {
        // 获取购物车列表
        BoundHashOperations<String, String, CartInfo> bound = redisTemplate.boundHashOps(getKey(userId));
        List<CartInfo> cartInfoList = bound.values();
        // 筛选已选中的商品
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            return cartInfoList.stream().filter(e -> {
                // 更新价格
                e.setSkuPrice(productFeignClient.getSkuPrice(e.getSkuId()));
                // 是否选中
                return e.getIsChecked() == 1;
            }).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    /**
     * 生成用户购物车的key
     */
    private String getKey(String userId) {
        return RedisConstant.CART_PREFIX + userId;
    }
}
